package br.com.fogas.database.dao.impl;

import java.sql.SQLException;
import java.util.List;

import br.com.fogas.database.IMetadata.IPlanoVisitas;
import br.com.fogas.database.dao.IPlanoVisitasDao;
import br.com.fogas.database.entidade.Cliente;
import br.com.fogas.database.entidade.PlanoVisitas;
import br.com.fogas.database.enums.PlanoVisitaStatusEnum;

import com.j256.ormlite.dao.BaseDaoImpl;
import com.j256.ormlite.support.ConnectionSource;

public class PlanoVisitasDao extends BaseDaoImpl<PlanoVisitas, Integer> implements IPlanoVisitasDao {
	
	public PlanoVisitasDao(ConnectionSource connectionSource) throws SQLException {
		super(connectionSource, PlanoVisitas.class);
	}
	
	@Override
	public List<PlanoVisitas> listarPlanoClientesPorLocal(Cliente local)
			throws SQLException {
		
		List<PlanoVisitas> planos = queryBuilder().where()
				.eq(IPlanoVisitas.cs_Local, false)
				.and().eq(IPlanoVisitas.local, local)
				.query();
		
		return planos;
	}
	
	@Override
	public List<PlanoVisitas> listarPlanoClientesPorLocalStatus(Cliente local,
			PlanoVisitaStatusEnum status) throws SQLException {
		
		List<PlanoVisitas> planos = queryBuilder().where()
				.eq(IPlanoVisitas.cs_Local, false)
				.and().eq(IPlanoVisitas.local, local)
				.and().eq(IPlanoVisitas.status, status.getId())
				.query();
		
		return planos;
	}

	@Override
	public PlanoVisitaStatusEnum statusVisitaLocal(Cliente local) throws SQLException {
		List<PlanoVisitas> planoLocais = listarPlanoClientesPorLocal(local);
		
		List<PlanoVisitas> finalizadas = listarPlanoClientesPorLocalStatus(local, PlanoVisitaStatusEnum.FINALIZADO);
		
		List<PlanoVisitas> canceladas = listarPlanoClientesPorLocalStatus(local, PlanoVisitaStatusEnum.CANCELADO);
		
		if(canceladas.size() == planoLocais.size()) {
			return PlanoVisitaStatusEnum.CANCELADO;
		} else if((finalizadas.size() + canceladas.size()) == planoLocais.size()) {
			return PlanoVisitaStatusEnum.FINALIZADO;
		} else {
			return PlanoVisitaStatusEnum.PENDENTE;
		}
	}

	@Override
	public List<PlanoVisitas> listarPlanoLocais() throws SQLException {
		List<PlanoVisitas> planos = queryBuilder()
				.where().eq(IPlanoVisitas.cs_Local, true)
				.query();
		
		for (PlanoVisitas plano : planos) {
			PlanoVisitaStatusEnum status = statusVisitaLocal(plano.getCliente());
			
			plano.setStatus(status.getId());
			
			if(status.equals(PlanoVisitaStatusEnum.CANCELADO)) {
				plano.setCs_Visitar(false);
			} else {
				plano.setCs_Visitar(true);
			}
			
			update(plano);
		}
		
		return planos;
	}

	@Override
	public void cancelarVisitaLocalVisitaClientes(PlanoVisitas planoLocal)
			throws SQLException {
		planoLocal.setStatus(PlanoVisitaStatusEnum.CANCELADO.getId());
		planoLocal.setCs_Visitar(false);
		update(planoLocal);
		
		List<PlanoVisitas> planoClientes = listarPlanoClientesPorLocalStatus(planoLocal.getCliente(), PlanoVisitaStatusEnum.PENDENTE);
		
		for (PlanoVisitas visita : planoClientes) {
			visita.setStatus(PlanoVisitaStatusEnum.CANCELADO.getId());
			visita.setCs_Visitar(false);
			update(visita);
		}
	}

	@Override
	public void deixarPendenteVisitaLocalVisitaClientes(PlanoVisitas planoLocal)
			throws SQLException {
		planoLocal.setStatus(PlanoVisitaStatusEnum.PENDENTE.getId());
		planoLocal.setCs_Visitar(true);
		update(planoLocal);
		
		List<PlanoVisitas> planoClientes = listarPlanoClientesPorLocalStatus(planoLocal.getCliente(), PlanoVisitaStatusEnum.CANCELADO);
		
		for (PlanoVisitas visita : planoClientes) {
			visita.setStatus(PlanoVisitaStatusEnum.PENDENTE.getId());
			visita.setCs_Visitar(true);
			update(visita);
		}
	}
	
	/*
	@Override
	public List<PlanoVisitas> listarPlanoShopping() throws SQLException {
		QueryBuilder<PlanoVisitas, Integer> query = queryBuilder();
		List<PlanoVisitas> planos = query.where().eq(IPlanoVisitas.localShopping, true).query();
		
		for (PlanoVisitas plano : planos) {
			PlanoVisitaStatusEnum statusPlanoLojasShopping = planoLojasShoppingFinalizado(plano.getCliente());
			
			plano.setStatus(statusPlanoLojasShopping.getId());
			
			if(statusPlanoLojasShopping.equals(PlanoVisitaStatusEnum.CANCELADO)) {
				plano.setVisitar(false);
			} else {
				plano.setVisitar(true);
			}
			
			update(plano);
		}
		
		return planos;
	}
	
	@Override
	public PlanoVisitaStatusEnum planoLojasShoppingFinalizado(Cliente shopping) throws SQLException {
		List<PlanoVisitas> planoLojas = listarPlanoLojasPorShopping(shopping);
		
		List<PlanoVisitas> finalizadas = listarPlanoLojasPorShoppingStatus(shopping, 
				PlanoVisitaStatusEnum.FINALIZADO.getId());
		
		List<PlanoVisitas> canceladas = listarPlanoLojasPorShoppingStatus(shopping, 
				PlanoVisitaStatusEnum.CANCELADO.getId());
		
		boolean shoppingFinalizado = (finalizadas.size() + canceladas.size()) == planoLojas.size();
		
		if(canceladas.size() == planoLojas.size()) {
			return PlanoVisitaStatusEnum.CANCELADO;
		} else {
			return shoppingFinalizado ? PlanoVisitaStatusEnum.FINALIZADO : PlanoVisitaStatusEnum.PENDENTE;
		}
	}

	@Override
	public List<PlanoVisitas> listarPlanoLojasPorShopping(Cliente shopping) throws SQLException {
		List<Integer> statusParams = new ArrayList<Integer>();
		statusParams.add(PlanoVisitaStatusEnum.NF_CANCELADA.getId());
		
		QueryBuilder<PlanoVisitas, Integer> query = queryBuilder();
		List<PlanoVisitas> planos = query.where()
				.eq(IPlanoVisitas.localShopping, false)
				.and().eq(IPlanoVisitas.shopping, shopping)
				.and().notIn(IPlanoVisitas.status, statusParams)
				.query();
		
		return planos;
	}

	@Override
	public List<PlanoVisitas> listarPlanoLojasPorShoppingStatus(
			Cliente shopping, Integer status) throws SQLException {
		QueryBuilder<PlanoVisitas, Integer> query = queryBuilder();
		List<PlanoVisitas> planos = query.where()
				.eq(IPlanoVisitas.localShopping, false)
				.and().eq(IPlanoVisitas.status, status)
				.and().eq(IPlanoVisitas.shopping, shopping).query();
		return planos;
	}

	@Override
	public void atualizarPlanoLojasShoppingVisitaPendente(PlanoVisitas planoVisitas) throws SQLException {
		planoVisitas.setStatus(PlanoVisitaStatusEnum.PENDENTE.getId());
		planoVisitas.setVisitar(true);
		update(planoVisitas);
		
		List<Integer> statusParams = new ArrayList<Integer>();
		statusParams.add(PlanoVisitaStatusEnum.NF_CANCELADA.getId());
		
		QueryBuilder<PlanoVisitas, Integer> query = queryBuilder();
		List<PlanoVisitas> planos = query.where()
				.eq(IPlanoVisitas.shopping, planoVisitas.getCliente())
				.and().notIn(IPlanoVisitas.status, statusParams)
				.query();
		
		for (PlanoVisitas visita : planos) {
			if(!visita.getStatusEnum().equals(PlanoVisitaStatusEnum.FINALIZADO)) {
				visita.setStatus(PlanoVisitaStatusEnum.PENDENTE.getId());
				visita.setVisitar(true);
				update(visita);
			}
		}
	}

	@Override
	public void atualizarPlanoLojasShoppingVisitaCancelada(PlanoVisitas planoVisitas) throws SQLException {
		planoVisitas.setStatus(PlanoVisitaStatusEnum.CANCELADO.getId());
		planoVisitas.setVisitar(false);
		update(planoVisitas);
		
		List<Integer> statusParams = new ArrayList<Integer>();
		statusParams.add(PlanoVisitaStatusEnum.NF_CANCELADA.getId());
		
		QueryBuilder<PlanoVisitas, Integer> query = queryBuilder();
		List<PlanoVisitas> planos = query.where()
				.eq(IPlanoVisitas.shopping, planoVisitas.getCliente())
				.and().notIn(IPlanoVisitas.status, statusParams)
				.query();
		
		for (PlanoVisitas visita : planos) {
			if(!visita.getStatusEnum().equals(PlanoVisitaStatusEnum.FINALIZADO)) {
				visita.setStatus(PlanoVisitaStatusEnum.CANCELADO.getId());
				visita.setVisitar(false);
				update(visita);
			}
		}
	}

	@Override
	public void atualizarPlanoLojasShoppingStatus(List<PlanoVisitas> planos, Integer status) throws SQLException {
		
		for (PlanoVisitas visita : planos) {
			visita.setStatus(status);
			update(visita);
		}
	}

	@Override
	public void atualizarPlanoLojaVisitaPendente(PlanoVisitas plano)
			throws SQLException {
		plano.setStatus(PlanoVisitaStatusEnum.PENDENTE.getId());
		plano.setVisitar(true);
		update(plano);
	}

	@Override
	public void atualizarPlanoLojaVisitaCancelada(PlanoVisitas plano)
			throws SQLException {
		plano.setStatus(PlanoVisitaStatusEnum.CANCELADO.getId());
		plano.setVisitar(false);
		update(plano);
	}
	*/
}